Android Develop Note
Meow King October 21, 2023 Updated: October 21, 2023 #android #note-
Configuration change will lead to complete recreation of Activity link: https://developer.android.com/guide/topics/resources/runtime-changes#recreation-example
The recreation also clears out any state kept as fields in the Activity or in any of its contained Fragment, View, or other objects.
-
Restrict activity recreation on configuration change (like orientation change) link: https://developer.android.com/guide/topics/resources/runtime-changes#restrict-activity
Make sure you also read the underneath section of this linked section:React to configuration changes in the View system
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
-
Mark message parts that aren't to be translated link: https://developer.android.com/guide/topics/resources/localization#mark-message-parts
<xliff:g id="time" example="5 days">%1$s</xliff:g>
-
Different Resolution Image: https://developer.android.com/training/multiscreen/screendensities#TaskProvideAltBmp
-
Use
Compose BOM
to manage Compose libraries
link: https://developer.android.com/jetpack/compose/bom
The versions of compose libraries that it maps: https://developer.android.com/jetpack/compose/bom/bom-mapping -
Create Multiple sub-project / module application.
Like nowinandroid
You can inspect the example layout by creating a multiple sub-project applicationgradle init
, then choosemultiple sub-projects
.
You can also convert one existing single module application into multiple one by (in android studio)- file -> new -> new module -> Android Library
You can even give the package name sharing the same prefix with your main project likepersonal.meowking.embark
(main)personal.meowking.embark.core
(new) - check project root
settings.gradle.kts
include(":app") include(":core")
- add
implementation(project(":core"))
in thedependencies
section in filebuild.gradle.kts
inapp
(main) project.
- file -> new -> new module -> Android Library
-
Accompanist Accompanist is a group of libraries that aim to supplement Jetpack Compose with features that are commonly required by developers but not yet available.
-
Side Effects, ViewModel Scope and Coroutine Scope from
rememberCoroutineScope()
for database operations Conclusion: useviewModelScope
for most of the operations. So place many operations in view model. When there are some operations that should be coupled tightly after data change like navigated back, we may put the data change operation and navigate back function inside a coroutine scope. Example coroutine scope is bind to the current Composable and may not survive during configuration changes like rotating screen. (See: link)
Side Effects is often useful when you have side effects that need to be restarted or cancelled based on specific state changes within a Composable without necessarily having UI survival requirements -
For regular expression, use
android.util.Patterns
library, which has provided some common regular expressions. Note: this library can only be used under android environment, so please test it inandroid test
. -
Room Database Flow usage:
- Initialize Once:
itemUiState
will not be automatically updated when the database updates because the stream is not collected continuously.init { viewModelScope.launch { itemUiState = itemsRepository.getItemStream(itemId) .filterNotNull() .first() // collect only once to set the initial state .toItemUiState(true) }
- Update automatically every time
viewModelScope.launch { itemsRepository.getItemStream(itemId) .filterNotNull() .collect { item -> itemUiState = item.toItemUiState(true) } }
- Initialize Once:
-
View Model methods choose
- For jetpack compose, I use
mutableStateOf
for a simple and straightforward state handling
var itemUiState by mutableStateOf(ItemUiState()) private set fun updateUiState(itemDetails: ItemDetails) { itemUiState = ItemUiState(itemDetails = itemDetails, isEntryValid = validateInput(itemDetails)) }
- Use
StateFlow
if you want to share the state across different app components, or you're working in a multi-platform project, or need the thread-safety and advanced capabilities offered by Kotlin Flows.
private val _uiState = MutableStateFlow(HomeUIState()) val uiState: StateFlow<HomeUIState> = _uiState.asStateFlow() fun setTestText(text: String) { _uiState.update {currentState -> currentState.copy( inputText = text ) } }
- For jetpack compose, I use
-
Using Hilt in jetpack compose: If you use
navigation-compose
library, please addandroidx.hilt:hilt-navigation-compose
to your dependencies, and usehiltViewModel
to replaceviewModel
.
Official Source: link
An excellent article using this approach: Room + Dagger Hilt Jetpack Compose Material 3 -
We don't need to encapsulate Room actions in
Dispatcher.IO
dispatcher, since it uses its own dispatcher which doesn't botherMain
Dispatcher.
Do I need to mention the coroutine dispatcher while working with Retrofit and Room?